<?php

declare(strict_types=1);

namespace App\Entities;

use Illuminate\Database\Eloquent\Model;

class ABaseEntity
{
    /**
     * @var Model
     */
    protected $model;

    /**
     * @return string
     */
    public function __toString()
    {
        return json_encode($this->model->toArray());
    }

    /**
     * @return Model
     */
    public static function getNewModelInstance()
    {
        $model = self::getSubModel(static::class);

        return new $model();
    }

    /**
     * 按主键搜索，并返回一个实例
     *
     * @return static
     */
    public static function find(int $id)
    {
        $model = self::getSubModel(static::class);

        $ret = $model::find($id);
        if ($ret === null) {
            return null;
            //return new static(new $model);
        }

        return new static($ret);
    }

    public static function insert(array $data)
    {
        $model = self::getSubModel(static::class);
        $model::insert($data);
    }

    /**
     * @return static
     */
    public static function getNewInstance()
    {
        return new static(self::getNewModelInstance());
    }

    /**
     * @return void
     */
    public function refresh()
    {
        $this->model->refresh();
    }

    /**
     * @return array
     */
    public function toArray()
    {
        return $this->model->toArray();
    }

    /**
     * @return Model
     */
    public function getOriginalModel()
    {
        return $this->model;
    }

    /**
     * 保存修改
     *
     * @return bool
     */
    public function save()
    {
        return $this->model->save();
    }

    /**
     * 删除
     */
    public function delete()
    {
        return $this->model->delete();
    }

    /**
     * @return string
     */
    private static function getSubModel(string $class)
    {
        try {
            // 1. 获取类对象
            $entityClass = new \ReflectionClass($class);

            // 2. 获取构造函数信息
            $constructor = $entityClass->getConstructor();

            // 3. 获取构造函数参数
            $params = $constructor->getParameters();
            $param  = $params[0] ?? null;

            if ($param) {
                $model = $param->getClass()->getName();
            } else {
                $model = '';
            }
        } catch (\ReflectionException $e) {
            $model = '';
        }

        return $model;
    }
}
